(function (zn){

    var __slice = Array.prototype.slice;
    var __toString = Object.prototype.toString;
    var __global = zn.global;

    /**
     * @class DOM
     * @namespace zn.ui.dom
     * @desc The element for dom.
     */
    zn.class('zn.ui.dom.DOM', zn.ui.core.Element, {
        partial: true,
        methods: {
            init: function (){
                this._domListeners = {};
            },
            on: function (name, handler, context){
                this.__attachListener(name);
                return this.super(name, handler, context), this;
            },
            off: function (name, handler, context){
                this.super(name, handler, context);
                if (!this.__listeners__[name].length) {
                    this.__detachListener(name);
                }

                return this;
            },
            upon: function (name, handler, context){
                this.__attachListener(name);
                return this.super(name, handler, context), this;
            },
            __attachListener: function (name) {
                var _domListeners = this._domListeners;
                if (!(name in _domListeners)) {
                    var _self = this,
                        _dom = _self._dom,
                        _listener = function (event) {
                            _self.fire(name, event);
                        };

                    _domListeners[name] = _listener;

                    if (name.charAt(0) === ':') {
                        _dom.addEventListener(name.slice(1), _listener, true);
                    }
                    else {
                        _dom.addEventListener(name, _listener);
                    }
                }
            },
            __detachListener: function (name) {
                var _domListeners = this._domListeners;
                if (name in _domListeners) {
                    var _dom = this._dom,
                        _listener = _domListeners[name];

                    if (name.charAt(0) === ':') {
                        _dom.removeEventListener(name.slice(1), _listener, true);
                    } else {
                        _dom.removeEventListener(name, _listener);
                    }
                }
            }
        }
    });

})(zn);
